/**
 * COPYRIGHT HangZhou Trustway Technology Company Limited
 * All right reserved.
 */
package com.robam.cloud.common.util;

import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.time.DateFormatUtils;

import java.text.DateFormat;
import java.text.ParseException;
import java.text.ParsePosition;
import java.text.SimpleDateFormat;
import java.util.*;

/**
 * @Description
 * @Author 薛铁琪
 * @CreateTime 2019-08-22 11:02
 * @Version 1.0
 */
@Slf4j
public class DateUtil {
    /**
     * 默认日期格式
     */
    private static String defaultDatePattern = null;

    public static final String DATESHOWFORMAT = "yyyy-MM-dd";

    /**
     * 默认日时间日期格式
     */
    private static String timePattern = "HH:mm";
    /**
     * 简洁日期格式
     */
    public static String simpleDatePattern = "yyyy-MM-dd";
    /**
     * 完整日期格式
     */
    public static String fullDatePattern = "yyyy-MM-dd HH:mm:ss";

    /**
     * @return String 日期格式
     * @throws
     * @Description: 获取日期格式
     * @author cj
     * @date 2016年3月23日
     */
    private static synchronized String getDatePattern() {
        if (null == defaultDatePattern) {
            defaultDatePattern = simpleDatePattern;
        }
        return defaultDatePattern;
    }

    /**
     * @param datePattern 日期格式,可空
     * @param strDate     日期字符串
     * @return Date 日期
     * @throws ParseException 转换异常
     * @Description: 字符串转化为日期
     * @author Administrator
     * @date 2016年3月23日
     */
    public static final Date convertStringToDate(String datePattern,
                                                 String strDate) throws ParseException {
        SimpleDateFormat df = null;
        Date date = null;
        if (null == datePattern) {
            df = new SimpleDateFormat(datePattern);
        } else {
            df = new SimpleDateFormat(getDatePattern());
        }
        if (log.isDebugEnabled()) { // debug模式输出
            log.debug("converting '" + strDate
                    + "' to date with datePattern '" + datePattern + "'");
        }
        try {
            date = df.parse(strDate);
        } catch (ParseException pe) {
            throw new ParseException(pe.getMessage(), pe.getErrorOffset());
        }
        return date;
    }

    /**
     * 日期转化为字符串
     *
     * @param datePattern 日期格式,可空
     * @param date        日期
     * @return 日期字符串
     * @author cj created 2015-12-13
     */
    public static final String convertDateToString(String datePattern, Date date) {
        if (null == datePattern) {
            datePattern = getDatePattern();
        }
        return getDateStr(datePattern, date);
    }

    /**
     * 对字符串日期的增减操作(单位：年)
     *
     * @param strDate    日期字符串操作对象，格式yyyy-MM-dd
     * @param flag       增/减标志 1-增加 0-减少
     * @param intYearVar 增减年数
     * @return 结果日期字符串
     * @author cj created 2015-12-13
     */
    public static String yearAddOrSubtract(String strDate, int flag,
                                           int intYearVar) {
        String returnDateStr = "";
        try {
            Date dt = convertStringToDate("yyyy-MM-dd", strDate);
            GregorianCalendar gc = new GregorianCalendar();
            SimpleDateFormat sf = new SimpleDateFormat("yyyy-MM-dd");
            gc.setTime(dt);
            if (flag == 1) {
                gc.add(GregorianCalendar.YEAR, +intYearVar);
            } else {
                gc.add(GregorianCalendar.YEAR, -intYearVar);
            }
            gc.set(gc.get(Calendar.YEAR), gc.get(Calendar.MONTH),
                    gc.get(Calendar.DATE));
            returnDateStr = sf.format(gc.getTime());
        } catch (ParseException e) {
            returnDateStr = "日期格式需为yyyy-MM-dd格式";
        }
        return returnDateStr;
    }

    /**
     * 日期字符串转化为指定格式日期字符串
     *
     * @param sourceDatePattern       源日期格式
     * @param sourceDateStr           源日期字符串
     * @param targetSourceDatePattern 目标日期格式
     * @return 目标日期字符串
     * @author cj created 2015-12-13
     */
    public static String conversionFormat(String sourceDatePattern,
                                          String sourceDateStr, String targetSourceDatePattern) {
        Date date = new Date();
        try {
            date = (new SimpleDateFormat(sourceDatePattern))
                    .parse(sourceDateStr);
        } catch (ParseException e) {
            e.printStackTrace();
        }
        return (new SimpleDateFormat(targetSourceDatePattern)).format(date);
    }

    /**
     * 获取日期时间字符串HH:mm
     *
     * @param date 日期
     * @return 时间字符串HH:mm
     * @author cj created 2015-12-13
     */
    public static String getDayTime(Date date) {
        return getDateStr(timePattern, date);
    }

    /**
     * 获取日期字符串
     *
     * @param datePattern 日期格式，可空默认取defaultDatePattern
     * @param date        日期
     * @return 日期字符串
     * @author cj created 2015-12-13
     */
    public static final String getDateStr(String datePattern, Date date) {
        if (null == date) {
            log.error("传入日期为空！");
        }
        if (null == datePattern) {
            datePattern = getDatePattern();
        }
        SimpleDateFormat df = null;
        String returnValue = "";
        df = new SimpleDateFormat(datePattern);
        returnValue = df.format(date);
        return (returnValue);
    }

    /**
     * 获取日期对应月份的第一天
     *
     * @param date 日期
     * @return 日期
     * @author cj created 2015-12-13
     */
    public static Date getMonthFirstDay(Date date) {
        Calendar ca = Calendar.getInstance();
        ca.setTime(date); // someDate 为你要获取的那个月的时间
        ca.set(Calendar.DAY_OF_MONTH, 1);
        return ca.getTime();
    }

    /**
     * 获取日期对应月份的最后一天
     *
     * @param date 日期
     * @return 日期
     * @author cj created 2015-12-13
     */
    public static Date getMonthLastDay(Date date) {
        Calendar ca = Calendar.getInstance();
        ca.setTime(date); // someDate 为你要获取的那个月的时间
        ca.set(Calendar.DAY_OF_MONTH, 1);
        ca.add(Calendar.MONTH, 1);
        ca.add(Calendar.DAY_OF_MONTH, -1);
        return ca.getTime();
    }

    /**
     * 获取几天后的日期
     *
     * @param date   日期
     * @param dayNum 增加几天
     * @return 日期
     * @author cj created 2015-12-13
     */
    public static Date addDateByDay(Date date, int dayNum) {
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(date);
        calendar.add(Calendar.DATE, dayNum);
        return calendar.getTime();
    }

    public static Date addDateByHour(Date date, int hourNum) {
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(date);
        calendar.add(Calendar.HOUR, hourNum);
        return calendar.getTime();
    }

    public static Date addDateByMinute(Date date, int minuteNum) {
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(date);
        calendar.add(Calendar.MINUTE, minuteNum);
        return calendar.getTime();
    }

    /**
     * 获取几个月后的日期
     *
     * @param date     日期
     * @param monthNum 增加几个月
     * @return 日期
     * @author cj created 2015-12-13
     */
    public static Date addDateByMonth(Date date, int monthNum) {
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(date);
        calendar.add(Calendar.MONTH, monthNum);
        return calendar.getTime();
    }

    /**
     * 获取几年后的日期
     *
     * @param date    日期
     * @param yearNum 增加几年
     * @return 日期
     * @author cj created 2015-12-13
     */
    public static Date addDateByYear(Date date, int yearNum) {
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(date);
        calendar.add(Calendar.YEAR, yearNum);
        return calendar.getTime();
    }

    /**
     * 获取当前服务器时间
     *
     * @return 日期
     * @author cj created 2015-12-13
     */
    public static Date getDate() {
        return new Date();
    }

    /**
     * 将字符串转换为Date类型
     *
     * @param date    字符串类型
     * @param pattern 格式
     * @return 日期类型
     */
    public static Date format(String date, String pattern) {
        if (pattern == null || pattern.equals("") || pattern.equals("null")) {
            pattern = "yyyy-MM-dd HH:mm:ss";
        }
        if (date == null || date.equals("") || date.equals("null")) {
            return new Date();
        }
        Date d = null;
        try {
            d = new SimpleDateFormat(pattern).parse(date);
        } catch (ParseException pe) {
        }
        return d;
    }

    public static String formatDate(Date date, String pattern) {
        String formatDate = null;
        if (StringUtil.isNotBlank(pattern)) {
            formatDate = DateFormatUtils.format(date, pattern);
        } else {
            formatDate = DateFormatUtils.format(date, "yyyy-MM-dd");
        }
        return formatDate;
    }

    /**
     * 日期格式化(String转换为String)
     *
     * @param date          日期字符串
     * @param oldPattern    传入的字符串的日期格式
     * @param patternString 处理结果日期的显示格式，如："YYYY-MM-DD"
     * @return
     * @throws ParseException
     * @author tjb
     */
    public static String getDateString(String date, String oldPattern,
                                       String patternString) throws ParseException {
        if (date == null) {
            return "";
        }
        if (date.length() < 10) {
            return "";
        }
        SimpleDateFormat formatter = new SimpleDateFormat(patternString,
                Locale.ENGLISH);
        SimpleDateFormat oldFormatter = new SimpleDateFormat(oldPattern,
                Locale.ENGLISH);
        int len = patternString.length();
        if (len > date.length()) {
            patternString = patternString.substring(0, date.length());
        }
        Date myDate = oldFormatter.parse(date);
        return formatter.format(myDate);
    }

    /**
     * 是否开始日期在结束日期之前(不包括相等)
     *
     * @param p_startDate
     * @param p_endDate
     * @return boolean 在结束日期前:ture;否则：false
     * @author zhuqx
     * @Date: 2006-10-31
     */
    public static boolean isStartDateBeforeEndDate(Date p_startDate,
                                                   Date p_endDate) throws ParseException {
        long l_startTime = getMillisOfDate(p_startDate);
        long l_endTime = getMillisOfDate(p_endDate);
        return (l_startTime - l_endTime < (long) 0) ? true : false;
    }

    /**
     * 获取2个字符日期的天数差
     *
     * @param p_startDate
     * @param p_endDate
     * @return 天数差
     * @author zhuqx
     * @Date: 2006-10-31
     */
    public static long getDaysOfTowDiffDate(String p_startDate, String p_endDate)
            throws ParseException {

        Date l_startDate = toUtilDateFromStrDateByFormat(p_startDate,
                "yyyy-MM-dd");
        Date l_endDate = toUtilDateFromStrDateByFormat(p_endDate, "yyyy-MM-dd");
        long l_startTime = getMillisOfDate(l_startDate);
        long l_endTime = getMillisOfDate(l_endDate);
        long betweenDays = (long) ((l_endTime - l_startTime) / (1000 * 60 * 60 * 24));
        return betweenDays;
    }

    /**
     * 字符型日期转化util.Date型日期
     *
     * @param p_format 格式:"yyyy-MM-dd" / "yyyy-MM-dd hh:mm:ss"
     * @Param:p_strDate 字符型日期
     * @Return:java.util.Date util.Date型日期
     * @Throws: ParseException
     * @Author: zhuqx
     * @Date: 2006-10-31
     */
    public static Date toUtilDateFromStrDateByFormat(
            String p_strDate, String p_format) throws ParseException {
        Date l_date = null;
        DateFormat df = new SimpleDateFormat(p_format);
        if (p_strDate != null && (!"".equals(p_strDate)) && p_format != null
                && (!"".equals(p_format))) {
            l_date = df.parse(p_strDate);
        }
        return l_date;
    }

    /**
     * 获取2个字符日期的周数差
     *
     * @param p_startDate
     * @param p_endDate
     * @return 周数差
     * @author zhuqx
     * @Date: 2006-10-31
     */
    public static long getWeeksOfTowDiffDate(String p_startDate,
                                             String p_endDate) throws ParseException {
        return getDaysOfTowDiffDate(p_startDate, p_endDate) / 7;
    }

    /**
     * 获取2个字符日期的月数差
     *
     * @param p_startDate
     * @param p_endDate
     * @return 月数差
     * @author zhuqx
     * @Date: 2006-10-31
     */
    public static long getMonthsOfTowDiffDate(String p_startDate,
                                              String p_endDate) throws ParseException {
        return getDaysOfTowDiffDate(p_startDate, p_endDate) / 30;
    }

    /**
     * 获取2个字符日期的年数差
     *
     * @param p_startDate
     * @param p_endDate
     * @return 年数差
     * @author zhuqx
     * @Date: 2006-10-31
     */
    public static long getYearsOfTowDiffDate(String p_startDate,
                                             String p_endDate) throws ParseException {
        return getDaysOfTowDiffDate(p_startDate, p_endDate) / 365;
    }

    /**
     * 在给定的日期基础上添加年，月，日、时，分，秒 例如要再2006－10－21（uitl日期）添加3个月，并且格式化为yyyy-MM-dd格式，
     * 这里调用的方式为 addDate(2006－10－21,3,Calendar.MONTH,"yyyy-MM-dd")
     *
     * @param p_startDate 给定的日期
     * @param p_count     时间的数量
     * @param p_field     添加的域
     * @param p_format    时间转化格式，例如：yyyy-MM-dd hh:mm:ss 或者yyyy-mm-dd等
     * @return 添加后格式化的时间
     * @Date: 2006-10-31
     */
    public static String addDate(Date p_startDate, int p_count, int p_field,
                                 String p_format) throws ParseException {

        // 年，月，日、时，分，秒
        int l_year = getYearOfDate(p_startDate);
        int l_month = getMonthOfDate(p_startDate) - 1;
        int l_day = getDayOfDate(p_startDate);
        int l_hour = getHourOfDate(p_startDate);
        int l_minute = getMinuteOfDate(p_startDate);
        int l_second = getSecondOfDate(p_startDate);
        Calendar l_calendar = new GregorianCalendar(l_year, l_month, l_day,
                l_hour, l_minute, l_second);
        l_calendar.add(p_field, p_count);
        return toStrDateFromUtilDateByFormat(l_calendar.getTime(), p_format);
    }

    /**
     * util.Date型日期转化指定格式的字符串型日期
     *
     * @param p_utilDate Date
     * @param p_format   String 格式1:"yyyy-MM-dd" 格式2:"yyyy-MM-dd hh:mm:ss EE"
     *                   格式3:"yyyy年MM月dd日 hh:mm:ss EE" 说明: 年-月-日 时:分:秒 星期 注意MM/mm大小写
     * @return String
     * @Author: zhuqx
     * @Date: 2006-10-31
     */
    public static String toStrDateFromUtilDateByFormat(
            Date p_utilDate, String p_format) throws ParseException {
        String l_result = "";
        if (p_utilDate != null) {
            SimpleDateFormat sdf = new SimpleDateFormat(p_format);
            l_result = sdf.format(p_utilDate);
        }
        return l_result;
    }

    /**
     * 获取距离中心多少时间的时间
     *
     * @param d          中心时间点
     * @param clndrField field
     * @param amount
     * @param amount     格式字符串
     * @return
     */
    public static Date getDistanceDate(Date d,
                                       int clndrField, int amount) {
        Calendar c = Calendar.getInstance();
        c.setTime(d);
        c.add(clndrField, amount);
        return c.getTime();
    }

    /**
     * 判断给定日期是不是润年
     *
     * @param p_date 给定日期
     * @return boolean 如果给定的年份为闰年，则返回 true；否则返回 false。
     * @Date: 2006-10-31
     */
    public static boolean isLeapYear(Date p_date) {
        int l_year = getYearOfDate(p_date);
        GregorianCalendar l_calendar = new GregorianCalendar();
        return l_calendar.isLeapYear(l_year);
    }

    /**
     * @param dataformate 日期的格式
     * @return String
     * @throws
     * @Description: 取出当天的起始日期：即为 当天的0时0分0秒
     * @author Administrator
     * @date 2016年3月23日
     */
    public static String getStartOfDay(String dataformate) {
        SimpleDateFormat sdf = new SimpleDateFormat(dataformate);
        Calendar c = Calendar.getInstance();
        c.setTime(new Date());
        c.set(Calendar.HOUR_OF_DAY, 0);
        c.set(Calendar.MINUTE, 0);
        c.set(Calendar.SECOND, 0);
        return sdf.format(c.getTime());
    }

    /**
     * @param strDate 日期
     * @param style   格式
     * @return int 年或月或日的数字表示
     * @throws
     * @Description: 从放有日期的字符串中得到，相应的年，月，日 style is "Y"or"y" 返回年 style is
     * "M"or"m" 返回月 style
     * @author Administrator
     * @date 2016年3月23日
     */

    public static int getYearMonthDate(String strDate, String style) {
        int year;
        int month;
        int day;
        int firstDash;
        int secondDash;
        if (strDate == null) {
            return 0;
        }
        firstDash = strDate.indexOf('-');
        secondDash = strDate.indexOf('-', firstDash + 1);
        if ((firstDash > 0) & (secondDash > 0)
                & (secondDash < strDate.length() - 1)) {
            year = Integer.parseInt(strDate.substring(0, firstDash));
            month = Integer.parseInt(strDate.substring(firstDash + 1,
                    secondDash));
            day = Integer.parseInt(strDate.substring(secondDash + 1));
        } else {
            return 0;
        }
        if (style.equalsIgnoreCase("Y")) {
            return year;
        } else if (style.equalsIgnoreCase("M")) {
            return month;
        } else if (style.equalsIgnoreCase("D")) {
            return day;
        } else {
            return 0;
        }
    }

    /**
     * @param jxlDate
     * @return Date
     * @throws
     * @Description: jxl时区转换
     * @author Administrator
     * @date 2016年3月23日
     */
    public static Date convertDate4JXL(Date jxlDate) {

        Date parseDate = null;
        try {
            TimeZone gmt = TimeZone.getTimeZone("GMT");
            DateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss",
                    Locale.getDefault());
            sdf.setTimeZone(gmt);
            String dateStr = sdf.format(jxlDate);
            TimeZone lo = TimeZone.getDefault();
            sdf.setTimeZone(lo);
            parseDate = sdf.parse(dateStr);
        } catch (ParseException e) {
            e.printStackTrace();
        }
        return parseDate;
    }

    /**
     * 字符型日期转化成sql.Date型日期
     *
     * @param p_strDate 字符型日期
     * @return java.sql.Date sql.Date型日期
     * @throws ParseException
     * @Author: zhuqx
     * @Date: 2006-10-31
     */
    public static java.sql.Date toSqlDateFromStrDate(String p_strDate)
            throws ParseException {
        java.sql.Date returnDate = null;
        DateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
        if (p_strDate != null && (!"".equals(p_strDate))) {
            returnDate = new java.sql.Date(sdf.parse(p_strDate).getTime());

        }
        return returnDate;
    }

    /**
     * @param date 指定日期
     * @return String 指定日期当天零点的日期字符串
     * @throws ParseException
     * @throws
     * @Description: 获取指定日期当天零点的日期字符串
     * @author Administrator
     * @date 2016年3月23日
     */
    public static String getDefineDateZero(Date date) throws ParseException {
        if (null == date) {
            return getCurrentDayZero();
        }

        return toStrDateFromUtilDateByFormat(date, simpleDatePattern)
                + " 00:00:00";
    }

    /**
     * @return String 当天零点的日期字符串
     * @throws ParseException
     * @throws
     * @Description: 获取当天零点的日期字符串
     * @author Administrator
     * @date 2016年3月23日
     */
    public static String getCurrentDayZero() throws ParseException {
        Date date = new Date();
        return toStrDateFromUtilDateByFormat(date, simpleDatePattern)
                + " 00:00:00";
    }

    /**
     * util.Date型日期转化sql.Date(年月日)型日期
     *
     * @Param: p_utilDate util.Date型日期
     * @Return: java.sql.Date sql.Date型日期
     * @Author: zhuqx
     * @Date: 2006-10-31
     */
    public static java.sql.Date toSqlDateFromUtilDate(Date p_utilDate) {
        java.sql.Date returnDate = null;
        if (p_utilDate != null) {
            returnDate = new java.sql.Date(p_utilDate.getTime());
        }
        return returnDate;
    }

    /**
     * util.Date型日期转化sql.Time(时分秒)型日期
     *
     * @Param: p_utilDate util.Date型日期
     * @Return: java.sql.Time sql.Time型日期
     * @Author: zhuqx
     * @Date: 2006-10-31
     */
    public static java.sql.Time toSqlTimeFromUtilDate(Date p_utilDate) {
        java.sql.Time returnDate = null;
        if (p_utilDate != null) {
            returnDate = new java.sql.Time(p_utilDate.getTime());
        }
        return returnDate;
    }

    /**
     * util.Date型日期转化sql.Date(时分秒)型日期
     *
     * @Param: p_utilDate util.Date型日期
     * @Return: java.sql.Timestamp sql.Timestamp型日期
     * @Author: zhuqx
     * @Date: 2006-10-31
     */
    public static java.sql.Timestamp toSqlTimestampFromUtilDate(
            Date p_utilDate) {
        java.sql.Timestamp returnDate = null;
        if (p_utilDate != null) {
            returnDate = new java.sql.Timestamp(p_utilDate.getTime());
        }
        return returnDate;
    }

    /**
     * sql.Date型日期转化util.Date型日期
     *
     * @Param: sqlDate sql.Date型日期
     * @Return: java.util.Date util.Date型日期
     * @Author: zhuqx
     * @Date: 2006-10-31
     */
    public static Date toUtilDateFromSqlDate(java.sql.Date p_sqlDate) {
        Date returnDate = null;
        if (p_sqlDate != null) {
            returnDate = new Date(p_sqlDate.getTime());
        }
        return returnDate;
    }

    /**
     * @param calendar
     * @return String
     * @throws
     * @Description: 将calendar转化为日期字符串
     * @author Lm
     * @date 2016年3月23日
     */
    public static String toStrDateFromCalendarByFormat(Calendar calendar) {
        int year = calendar.get(Calendar.YEAR);

        int month = calendar.get(Calendar.MONTH) + 1;

        int day = calendar.get(Calendar.DAY_OF_MONTH);

        String _yystr = "", _mmstr = "", _ddstr = "";
        _yystr = "" + year;
        _mmstr = "" + month;
        if (month < 10) {
            _mmstr = "0" + month;
        }
        _ddstr = "" + day;
        if (day < 10) {
            _ddstr = "0" + day;
        }

        String daystr = _yystr + "-" + _mmstr + "-" + _ddstr;

        return daystr;
    }

    /**
     * @param dateformat
     * @return String
     * @throws
     * @Description: 获取当天时间
     * @author Lm
     * @date 2016年3月22日
     */
    public static String getNowTime(String dateformat) {
        Date now = new Date();
        SimpleDateFormat dateFormat = new SimpleDateFormat(dateformat);// 可以方便地修改日期格式
        String hehe = dateFormat.format(now);
        return hehe;
    }

    /**
     * 获取字符日期一个月的天数
     *
     * @param p_date
     * @return 天数
     * @author zhuqx
     */
    public static long getDayOfMonth(Date p_date) throws ParseException {
        int year = getYearOfDate(p_date);
        int month = getMonthOfDate(p_date) - 1;
        int day = getDayOfDate(p_date);
        int hour = getHourOfDate(p_date);
        int minute = getMinuteOfDate(p_date);
        int second = getSecondOfDate(p_date);
        Calendar l_calendar = new GregorianCalendar(year, month, day, hour,
                minute, second);
        return l_calendar.getActualMaximum(Calendar.DAY_OF_MONTH);
    }

    /**
     * 获取指定月份的第一天
     *
     * @param p_strDate 指定月份
     * @param p_format  日期格式
     * @return String 时间字符串
     * @author zhuqx
     * @Date: 2006-10-31
     */
    public static String getDateOfMonthBegin(String p_strDate, String p_format)
            throws ParseException {
        Date date = toUtilDateFromStrDateByFormat(p_strDate, p_format);
        return toStrDateFromUtilDateByFormat(date, "yyyy-MM") + "-01";
    }

    /**
     * 获取指定月份的最后一天
     *
     * @param p_strDate 指定月份
     * @param p_format  日期格式
     * @return String 时间字符串
     * @author zhuqx
     * @Date: 2006-10-31
     */
    public static String getDateOfMonthEnd(String p_strDate, String p_format)
            throws ParseException {
        Date date = toUtilDateFromStrDateByFormat(
                getDateOfMonthBegin(p_strDate, p_format), p_format);
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(date);
        calendar.add(Calendar.MONTH, 1);
        calendar.add(Calendar.DAY_OF_YEAR, -1);
        return toStrDateFromUtilDateByFormat(calendar.getTime(), p_format);
    }

    /**
     * 获取指定年份的第一天
     *
     * @param p_strDate 指定年份
     * @param p_format
     * @return
     * @throws ParseException
     */
    public static String getDateOfYearBegin(String p_strDate, String p_format)
            throws ParseException {
        Date date = toUtilDateFromStrDateByFormat(p_strDate, p_format);
        return toStrDateFromUtilDateByFormat(date, "yyyy") + "-01-01";
    }

    /**
     * 获取指定年份的最后一天
     *
     * @param p_strDate 指定月份
     * @param p_format  日期格式
     * @return String 时间字符串
     * @author zhuqx
     * @Date: 2006-10-31
     */
    public static String getDateOfYearEnd(String p_strDate, String p_format)
            throws ParseException {
        Date date = toUtilDateFromStrDateByFormat(
                getDateOfYearBegin(p_strDate, p_format), p_format);
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(date);
        calendar.add(Calendar.YEAR, 1);
        calendar.add(Calendar.DAY_OF_YEAR, -1);
        return toStrDateFromUtilDateByFormat(calendar.getTime(), p_format);
    }


    public static String getDateOfWeekBegin(String p_strDate, String p_format) throws ParseException {
        Date InputDate = new SimpleDateFormat(p_format).parse(p_strDate);
        Calendar cDate = Calendar.getInstance();
        cDate.setFirstDayOfWeek(Calendar.MONDAY);
        cDate.setTime(InputDate);
        Calendar firstDate = Calendar.getInstance();
        firstDate.setFirstDayOfWeek(Calendar.MONDAY);
        firstDate.setTime(InputDate);

        if (cDate.get(Calendar.WEEK_OF_YEAR) == 1 && cDate.get(Calendar.MONTH) == 11) {
            firstDate.set(Calendar.YEAR, cDate.get(Calendar.YEAR) + 1);
        }

        int typeNum = cDate.get(Calendar.WEEK_OF_YEAR);
        firstDate.set(Calendar.WEEK_OF_YEAR, typeNum);
        firstDate.set(Calendar.DAY_OF_WEEK, Calendar.MONDAY);
        //所在周开始日期
        return new SimpleDateFormat(p_format).format(firstDate.getTime());
    }


    public static String getDateOfWeekEnd(String p_strDate, String p_format) throws ParseException {
        Date InputDate = new SimpleDateFormat(p_format).parse(p_strDate);
        Calendar cDate = Calendar.getInstance();
        cDate.setFirstDayOfWeek(Calendar.MONDAY);
        cDate.setTime(InputDate);

        Calendar lastDate = Calendar.getInstance();
        lastDate.setFirstDayOfWeek(Calendar.MONDAY);
        lastDate.setTime(InputDate);

        if (cDate.get(Calendar.WEEK_OF_YEAR) == 1 && cDate.get(Calendar.MONTH) == 11) {
            lastDate.set(Calendar.YEAR, cDate.get(Calendar.YEAR) + 1);
        }

        int typeNum = cDate.get(Calendar.WEEK_OF_YEAR);
        lastDate.set(Calendar.WEEK_OF_YEAR, typeNum);
        lastDate.set(Calendar.DAY_OF_WEEK, Calendar.SUNDAY);
        //所在周结束日期
        return new SimpleDateFormat(p_format).format(lastDate.getTime());
    }

    /**
     * 获取当前年份及之前5年 年份列表
     *
     * @param n 当前年份向前年份数
     * @return
     */
    public static List<Integer> getYearList(int n) {
        Calendar calendar = Calendar.getInstance();
        List<Integer> yearList = new ArrayList<Integer>();
        int nowYear = calendar.get(Calendar.YEAR);
        for (int i = 0; i < n + 1; i++) {
            yearList.add(nowYear - i);
        }
        return yearList;
    }

    /**
     * 获取月份列表
     *
     * @return
     */
    public static List<String> getMonthList() {
        List<String> monthList = new ArrayList<String>();
        for (int i = 0; i < 12; i++) {
            monthList.add(StringUtil.appendZero(i + 1 + "", 2));
        }
        return monthList;
    }

    /**
     * 获取小时列表
     *
     * @return
     */
    public static List<String> getHourList() {
        List<String> hourList = new ArrayList<String>();
        for (int i = -1; i < 23; i++) {
            hourList.add(StringUtil.appendZero(i + 1 + "", 2));
        }
        return hourList;
    }

    /**
     * 得到二个日期间的间隔小时数
     */
    public static String getTwoHour(Date sj1, Date sj2) {
        long hour = 0;
        try {
            hour = (sj1.getTime() - sj2.getTime()) / (60 * 60 * 1000);
        } catch (Exception e) {
            return "";
        }
        return hour + "";
    }

    /**
     * 根据一个日期，返回是星期几的字符串
     */
    public static String getWeek(String sdate) {
        // 再转换为时间
        Date date = strToDate(sdate);
        Calendar c = Calendar.getInstance();
        c.setTime(date);
        return new SimpleDateFormat("EEEE").format(c.getTime());
    }

    /**
     * 将短时间格式字符串转换为时间 yyyy-MM-dd
     */
    public static Date strToDate(String strDate) {
        SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd");
        ParsePosition pos = new ParsePosition(0);
        Date strtodate = formatter.parse(strDate, pos);
        return strtodate;
    }

    // 计算当月最后一天,返回字符串
    public static String getDefaultDay() {
        String str = "";
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");

        Calendar lastDate = Calendar.getInstance();
        lastDate.set(Calendar.DATE, 1);// 设为当前月的1号
        lastDate.add(Calendar.MONTH, 1);// 加一个月，变为下月的1号
        lastDate.add(Calendar.DATE, -1);// 减去一天，变为当月最后一天

        str = sdf.format(lastDate.getTime());
        return str;
    }

    // 上月第一天
    public static String getPreviousMonthFirst() {
        String str = "";
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");

        Calendar lastDate = Calendar.getInstance();
        lastDate.set(Calendar.DATE, 1);// 设为当前月的1号
        lastDate.add(Calendar.MONTH, -1);// 减一个月，变为下月的1号
        str = sdf.format(lastDate.getTime());
        return str;
    }

    // 获取当月第一天
    public static String getFirstDayOfMonth() {
        String str = "";
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");

        Calendar lastDate = Calendar.getInstance();
        lastDate.set(Calendar.DATE, 1);// 设为当前月的1号
        str = sdf.format(lastDate.getTime());
        return str;
    }

    // 获得当前日期与本周日相差的天数
    private static int getMondayPlus() {
        Calendar cd = Calendar.getInstance();
        // 获得今天是一周的第几天，星期日是第一天，星期二是第二天......
        int dayOfWeek = cd.get(Calendar.DAY_OF_WEEK) - 1; // 因为按中国礼拜一作为第一天所以这里减1
        log.info("相差天数:" + dayOfWeek);
        if (dayOfWeek == 1) {
            return 0;
        } else {
            return 1 - dayOfWeek;
        }
    }

    // 获得相应周的周六的日期
    public static String getSaturday() {
        int mondayPlus = getMondayPlus();
        GregorianCalendar currentDate = new GregorianCalendar();
        currentDate.add(GregorianCalendar.DATE, mondayPlus + 7 * 0 + 5);
        Date monday = currentDate.getTime();
        DateFormat df = new SimpleDateFormat("yyyy-MM-dd");
        String preMonday = df.format(monday);
        return preMonday;
    }

    // 获得本周星期日的日期
    public static String getCurrentWeekday() {
        int mondayPlus = getMondayPlus();
        GregorianCalendar currentDate = new GregorianCalendar();
        currentDate.add(GregorianCalendar.DATE, mondayPlus + 6);
        Date monday = currentDate.getTime();

        DateFormat df = new SimpleDateFormat("yyyy-MM-dd");
        String preMonday = df.format(monday);
        return preMonday;
    }

    /**
     * @return String
     * @throws
     * @Description: 获得上周星期日的日期
     * @author Administrator
     * @date 2016年3月25日
     */
    public static String getPreviousWeekSunday() {
        int mondayPlus = getMondayPlus();
        GregorianCalendar currentDate = new GregorianCalendar();
        currentDate.add(GregorianCalendar.DATE, mondayPlus - 1);
        Date monday = currentDate.getTime();
        DateFormat df = new SimpleDateFormat("yyyy-MM-dd");
        String preMonday = df.format(monday);
        return preMonday;
    }

    /**
     * @return String 日期
     * @throws
     * @Description: 获得上周星期一的日期
     * @author Administrator
     * @date 2016年3月25日
     */
    public static String getPreviousWeekday() {
        int mondayPlus = getMondayPlus();
        GregorianCalendar currentDate = new GregorianCalendar();
        currentDate.add(GregorianCalendar.DATE, mondayPlus - 7);
        Date monday = currentDate.getTime();
        DateFormat df = new SimpleDateFormat("yyyy-MM-dd");
        String preMonday = df.format(monday);
        return preMonday;
    }

    // 获得下周星期一的日期
    public static String getNextMonday() {
        int mondayPlus = getMondayPlus();
        GregorianCalendar currentDate = new GregorianCalendar();
        currentDate.add(GregorianCalendar.DATE, mondayPlus + 7);
        Date monday = currentDate.getTime();
        DateFormat df = new SimpleDateFormat("yyyy-MM-dd");
        String preMonday = df.format(monday);
        return preMonday;
    }

    // 获取当前日期的前一小时
    public static Date getLastHour() {
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(new Date());
        calendar.add(Calendar.HOUR_OF_DAY, -1);
        return calendar.getTime();
    }

    /**
     * 日期格式转换 DATE to DATE
     *
     * @param _date  日期
     * @param patten 处理结果日期的显示格式，如："YYYY-MM-DD"
     * @return
     */
    public static Date dateToDate(Date _date, String patten) {
        String dateStr = "";
        SimpleDateFormat formatter = new SimpleDateFormat(patten);
        try {
            if (_date != null) {
                dateStr = formatter.format(_date);
            }
            return formatter.parse(dateStr);
        } catch (ParseException e) {
        }
        return null;
    }

    /**
     * 获取日期是第几周
     *
     * @param date
     * @return
     */
    public static int getWeek(Date date) {
        Calendar ca = Calendar.getInstance();
        ca.setTime(date);
        return ca.get(Calendar.DAY_OF_WEEK);
    }

    // -----------------获取指定日期的年份，月份，日份，小时，分，秒，毫秒----------------------------

    /**
     * @param p_date
     * @return int
     * @throws
     * @Description: 获取指定日期的年份
     * @author Administrator
     * @date 2016年3月22日
     */
    public static int getYearOfDate(Date p_date) {
        Calendar c = Calendar.getInstance();
        c.setTime(p_date);
        return c.get(Calendar.YEAR);
    }

    /**
     * 获取指定日期的月份
     *
     * @param p_date util.Date日期
     * @return int 月份
     * @author zhuqx
     * @Date: 2006-10-31
     */
    public static int getMonthOfDate(Date p_date) {
        Calendar c = Calendar.getInstance();
        c.setTime(p_date);
        return c.get(Calendar.MONTH) + 1;
    }

    /**
     * 获取指定日期的日份
     *
     * @param p_date util.Date日期
     * @return int 日份
     * @author zhuqx
     * @Date: 2006-10-31
     */
    public static int getDayOfDate(Date p_date) {
        Calendar c = Calendar.getInstance();
        c.setTime(p_date);
        return c.get(Calendar.DAY_OF_MONTH);
    }

    /**
     * 获取指定日期的小时
     *
     * @param p_date util.Date日期
     * @return int 日份
     * @author zhuqx
     * @Date: 2006-10-31
     */
    public static int getHourOfDate(Date p_date) {
        Calendar c = Calendar.getInstance();
        c.setTime(p_date);
        return c.get(Calendar.HOUR_OF_DAY);
    }

    /**
     * 获取指定日期的分钟
     *
     * @param p_date util.Date日期
     * @return int 分钟
     * @author zhuqx
     * @Date: 2006-10-31
     */
    public static int getMinuteOfDate(Date p_date) {
        Calendar c = Calendar.getInstance();
        c.setTime(p_date);
        return c.get(Calendar.MINUTE);
    }

    /**
     * 获取指定日期的秒钟
     *
     * @param p_date util.Date日期
     * @return int 秒钟
     * @author zhuqx
     * @Date: 2006-10-31
     */
    public static int getSecondOfDate(Date p_date) {
        Calendar c = Calendar.getInstance();
        c.setTime(p_date);
        return c.get(Calendar.SECOND);
    }

    /**
     * 获取指定日期的毫秒
     *
     * @param p_date util.Date日期
     * @return long 毫秒
     * @author zhuqx
     * @Date: 2006-10-31
     */
    public static long getMillisOfDate(Date p_date) {
        Calendar c = Calendar.getInstance();
        c.setTime(p_date);
        return c.getTimeInMillis();
    }

    /**
     * 日期格式化(Date转换为String)
     *
     * @param _date         日期
     * @param patternString 处理结果日期的显示格式，如："YYYY-MM-DD"
     * @return
     */
    public static String getDateString(Date _date, String patternString) {
        String dateString = "";
        if (_date != null) {
            SimpleDateFormat formatter = new SimpleDateFormat(patternString);
            dateString = formatter.format(_date);
        }
        return dateString;
    }

    /**
     * 日期格式化(String转换为Date)
     *
     * @param dateStr 日期字符串
     * @param patten  处理结果日期的显示格式，如："YYYY-MM-DD"
     * @return
     */
    public static Date getDateToString(String dateStr, String patten) {
        if (StringUtil.isBlank(dateStr)) {
            return null;
        }
        SimpleDateFormat formatter = new SimpleDateFormat(patten);
        try {
            return formatter.parse(dateStr);
        } catch (ParseException e) {
            e.printStackTrace();
        }
        return null;
    }

    public static Date getDayFirst(Date date) {
        Calendar calendar1 = Calendar.getInstance();
        calendar1.setTime(date);
        calendar1.set(calendar1.get(Calendar.YEAR), calendar1.get(Calendar.MONTH), calendar1.get(Calendar.DAY_OF_MONTH),
                0, 0, 0);
        Date beginOfDate = calendar1.getTime();
        return beginOfDate;
    }

    public static int getCurrentDay() {
        Calendar cal = Calendar.getInstance();
        cal.setTime(new Date());
        int w = cal.get(Calendar.DAY_OF_WEEK) - 1;
        return w;
    }

}
